import scala.collection.mutable

object InheritanceAndPolymorphismDemo extends App {
  // 1. 定义父类：校园人员
  abstract class CampusPerson(
                      val id: String,
                      var name: String,
                      var gender: String,
                      var contact: String
                    ) {
    // 共同行为：显示基本信息
    def showBasicInfo(): Unit = {
      println(s"ID: $id")
      println(s"姓名: $name")
      println(s"性别: $gender")
      println(s"联系方式: $contact")
    }

    // 抽象行为：工作/学习内容（由子类实现）
    def work(): String
  }

  // 2. 定义子类：学生（继承自CampusPerson）
  class Student(
                 id: String,
                 name: String,
                 gender: String,
                 contact: String,
                 var major: String,
                 var grade: Int
               ) extends CampusPerson(id, name, gender, contact) {
    // 特有属性：已修课程
    private val completedCourses = mutable.Set.empty[String]

    // 特有方法：添加已修课程
    def addCompletedCourse(courseId: String): Unit = {
      completedCourses += courseId
    }

    // 实现父类的抽象方法
    override def work(): String = {
      s"学生${name}正在学习${major}专业课程, 已修${completedCourses.size}门课"
    }

    // 重写显示信息方法
    override def showBasicInfo(): Unit = {
      super.showBasicInfo() // 调用父类方法
      println(s"专业: $major")
      println(s"年级: $grade")
    }
  }

  // 3. 定义子类：教师（继承自CampusPerson）
  class Teacher(
                 id: String,
                 name: String,
                 gender: String,
                 contact: String,
                 var title: String,
                 var department: String
               ) extends CampusPerson(id, name, gender, contact) {
    // 特有属性：教授课程
    private val teachingCourses = mutable.Set.empty[String]

    // 特有方法：添加教授课程
    def addTeachingCourse(courseId: String): Unit = {
      teachingCourses += courseId
    }

    // 实现父类的抽象方法
    override def work(): String = {
      s"教师${name} (${title}) 在${department}系任教,教授${teachingCourses.size}门课"
    }

    // 重写显示信息方法
    override def showBasicInfo(): Unit = {
      super.showBasicInfo()
      println(s"职称: $title")
      println(s"部门: $department")
    }
  }

  // 4. 定义子类：行政人员（继承自CampusPerson）
  class Staff(
               id: String,
               name: String,
               gender: String,
               contact: String,
               var position: String,
               var office: String
             ) extends CampusPerson(id, name, gender, contact) {
    // 实现父类的抽象方法
    override def work(): String = {
      s"行政人员${name}担任${position}, 在${office}办公"
    }

    // 重写显示信息方法
    override def showBasicInfo(): Unit = {
      super.showBasicInfo()
      println(s"职位: $position")
      println(s"办公室: $office")
    }
  }

  // 5. 多态演示：统一管理不同类型的人员
  val people: List[CampusPerson] = List(
    new Student("S2025001", "张三", "男", "13800138000", "计算机", 2025),
    new Teacher("T1001", "李四", "女", "13900139000", "教授", "计算机"),
    new Staff("ST2001", "王五", "男", "13600136000", "行政主管", "办公楼201")
  )

  // 添加一些课程信息
  val student = people(0).asInstanceOf[Student]
  student.addCompletedCourse("C101")
  student.addCompletedCourse("C102")
  val teacher = people(1).asInstanceOf[Teacher]
  teacher.addTeachingCourse("C101")

  // 6. 多态行为：调用同一方法，不同实现
  println("===校园人员工作状态===")
  people.foreach { person =>
    println(person.work())
  }

  // 7. 统一处理不同类型人员
  println("\n===校园人员信息===")
  people.foreach { person =>
    println("--------")
    person.showBasicInfo()
  }

  // 8. 类型检查与转换
  println("\n===人员类型检查===")
  people.foreach { person =>
    val personType = person match {
      case _: Student => "学生"
      case _: Teacher => "教师"
      case _: Staff => "行政人员"
      case _ => "未知类型"
    }
    println(s"${person.name} 是 $personType")
  }
}
